package mosdi.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/** Similar to ArrayList, but the implementation is backed by arrays of primitive ints 
 *  rather than Integer objects. */
public class IntArrayList implements Collection<Integer> {

	private static final int initialSize = 20;
	private static final double growthFactor = 1.4;
	private int[] array;
	private int size;
	
	public IntArrayList() {
		clear();
	}
	
	public int get(int index) {
		if ((index<0) || (index>=size)) throw new IndexOutOfBoundsException();
		return array[index];
	}
	
	public void set(int index, int value) {
		if ((index<0) || (index>=size)) throw new IndexOutOfBoundsException();
		array[index] = value;
	}
	
	@Override
	public int size() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public boolean contains(Object o) {
		if (o == null) return false;
		if (!(o instanceof Integer)) return false;
		int sought = (Integer)o;
		for (int i=0; i<size; ++i) {
			if (array[i]==sought) return true;
		}
		return false;
	}

	private class IntArrayListIterator implements Iterator<Integer> {
		private int i;
		public IntArrayListIterator() {
			super();
			i = 0;
		}
		@Override
		public boolean hasNext() { return i<size; }
		@Override
		public Integer next() { return array[i++]; }
 		@Override
		public void remove() { throw new UnsupportedOperationException(); }
	}
	
	@Override
	public Iterator<Integer> iterator() {
		return new IntArrayListIterator();
	}

	@Override
	public Integer[] toArray() {
		Integer[] a = new Integer[size];
		for (int i=0; i<size; ++i) a[i] = array[i];
		return a;
	}

	public int[] toIntArray() {
		return Arrays.copyOf(array, size);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T[] toArray(T[] a) {
		if ((a==null) || (a.length<size)) {
			a = (T[]) new Integer[size];
		}
		for (int i=0; i<size; ++i) a[i] = (T)((Integer)array[i]);
		if (a.length>size) a[size] = null;
		return a;
	}

	@Override
	public boolean add(Integer e) {
		if (array.length==size) {
			array = Arrays.copyOf(array, (int)(array.length*growthFactor));
		}
		array[size++] = e;
		return true;
	}

	@Override
	public boolean remove(Object o) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		for (Object o : c) {
			if (!contains(o)) return false;
		}
		return true;
	}

	@Override
	public boolean addAll(Collection<? extends Integer> c) {
		if (array.length<size+c.size()) {
			array = Arrays.copyOf(array, (int)((array.length+c.size())*growthFactor));
		}
		for (Integer i : c) {
			array[size++] = i;
		}
		return true;
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void clear() {
		array = new int[initialSize];
		size = 0;
	}

}
